package com.shiroa.shiro;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shiroa.entity.SysMenu;
import com.shiroa.entity.SysRole;
import com.shiroa.entity.SysUser;
import com.shiroa.service.ISysMenuService;
import com.shiroa.service.ISysRoleService;
import com.shiroa.service.ISysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


public class ShiroRealm extends AuthorizingRealm  {
    @Autowired
    ISysRoleService sysRoleService;
    @Autowired
    ISysMenuService iSysMenuService;
    @Autowired
    private ISysUserService userService;

    public ShiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher)  {
        super(hashedCredentialsMatcher);
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
        List<SysRole> list =sysRoleService.getByUserId(user.getUserId());
        if(list.isEmpty()){
            throw new RuntimeException("请先授权");
        }
        List<Long> roleIdList = list.stream().mapToLong(SysRole::getRoleId).boxed().collect(Collectors.toList());
        List<SysMenu> menuList = iSysMenuService.getByRoleIdList(roleIdList);
        Set<String> roleNames = list.stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
        Set<String> permeList = menuList.stream().filter(item -> StringUtils.hasText(item.getPerms()))
                .map(SysMenu::getPerms).collect(Collectors.toSet());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRoles(roleNames);
        authorizationInfo.addStringPermissions(permeList);
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String name = (String)authenticationToken.getPrincipal();
        SysUser user = userService.getOne(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getUserName,name));
        if(user!=null){
            return new SimpleAuthenticationInfo(user,user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
        }
        return null;
    }
}
